import Taro, { useRouter } from '@tarojs/taro';
import type { RoutePageData } from '../../types/taro-route.config';
import { useRef } from 'react';
import { log } from './appLog';

let currentId = 0;
const pages: {
  id: number;
  page: string;
  data: any;
}[] = [];

const _Taro_navigateTo = Taro.navigateTo;
const _Taro_navigateBack = Taro.navigateBack;
const _Taro_redirectTo = Taro.redirectTo;
const _Taro_reLaunch = Taro.reLaunch;

export const getPages = () => {
  return pages;
};

let backData = null;

export const getPageBackData = () => {
  return backData;
};

export const setPageBackData = (data: any) => {
  backData = data;
};

const beforePushPage = (routeData: RoutePageData) => {
  let url = routeData.url;
  let page = '';
  if (url.includes('?')) {
    page = url.split('?')[0];
  } else {
    page = url;
  }
  let params = routeData.params || {};
  if (Object.keys(params).length) {
    let needFirstAnd = true;
    if (!url.includes('?')) {
      url += '?';
    } else {
      needFirstAnd = false;
    }
    Object.keys(params).forEach((key, index) => {
      let value = params[key];
      if (typeof value === 'object') {
        console.error('params禁止上传对象:' + key);
      }
      url += `${index != 0 && needFirstAnd ? '&' : ''}${key}=${params[key]}`;
    });
  }
  let id = currentId++;
  pages.push({
    id,
    page: page,
    data: routeData.data,
  });
  return {
    url,
    id,
  };
};

let preClickTime = 0;
function checkClickTime() {
  let bool = true;
  const now = Date.now();
  if (preClickTime && now - preClickTime < 200) {
    bool = false;
  }
  preClickTime = now;
  return bool;
}

/** 保留当前页面，跳转到应用内的某个页面 */
export const navigateTo = (routeData: RoutePageData) => {
  if (!checkClickTime()) return;
  const { url, id } = beforePushPage(routeData);
  console.log('navigateTo', routeData.url, { params: routeData.params, data: routeData.data });
  log('navigateTo ' + JSON.stringify(routeData));
  _Taro_navigateTo({
    url,
    success: res => {
      routeData.success?.(res);
      if (routeData.onBack) {
        Taro.eventCenter.once('onBackPageWithData-' + id, data => {
          routeData.onBack?.(data);
        });
      }
    },
    fail: res => {
      routeData.fail?.(res);
    },
  });
};

/** 关闭当前页面，返回上一页面或多级页面。可通过 getCurrentPages 获取当前的页面栈，决定需要返回几层 */
export const navigateBack = (option?: (Taro.navigateBack.Option & { backData?: any }) | undefined) => {
  if (!checkClickTime()) return;
  console.log('navigateBack', option);
  const delta = option?.delta || 1;
  log('navigateTo ' + JSON.stringify(option));
  if (pages.length > delta) {
    _Taro_navigateBack(option);
  } else {
    console.warn(`页面返回层数不足:${pages.length}<=${delta}`);
    redirectTo({ url: '/pages/index/index' });
  }
};

/** 关闭当前页面，跳转到应用内的某个页面 */
export const redirectTo = (routeData: RoutePageData) => {
  const { url } = beforePushPage(routeData);
  console.log('redirectTo', routeData.url, { params: routeData.params, data: routeData.data });
  log('navigateTo ' + JSON.stringify(routeData));
  _Taro_redirectTo({
    url,
    success: routeData.success,
    fail: res => {
      routeData.fail?.(res);
    },
  });
};

/** 关闭所有页面，打开到应用内的某个页面  */
export const reLaunch = (routeData: RoutePageData) => {
  const { url } = beforePushPage(routeData);
  console.log('reLaunch', routeData.url, { params: routeData.params, data: routeData.data });
  log('navigateTo ' + JSON.stringify(routeData));
  const pagesBak = pages.concat();
  const currentPage = pages.pop()!;
  pages.length = 0;
  pages.push(currentPage);
  _Taro_reLaunch({
    url,
    success: routeData.success,
    fail: res => {
      routeData.fail?.(res);
      pagesBak.forEach(v => pages.push(v));
    },
  });
};

export const useRouterData = () => {
  const router = useRouter();
  const idRef = useRef(pages[Taro.getCurrentPages().length - 1]?.id);
  return {
    ...router,
    data: pages.find(v => v.id == idRef.current)?.data,
    pageId: idRef.current,
  };
};

function init() {
  pages.push({
    id: currentId++,
    page: Taro.getCurrentInstance().router?.path || '',
    data: {},
  });
}

init();

Taro.navigateTo = navigateTo as any;
Taro.redirectTo = redirectTo as any;
Taro.reLaunch = reLaunch as any;
Taro.navigateBack = navigateBack as any;
